﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;

namespace PRScreenWithKinect
{
    class Gesture
    {
        public Gesture(int width, int height, Kinect kinect)
        {
            this.width = width;
            this.height = height;
            verticalStat = "up";
            this.kinect = kinect;
        }
        private Kinect kinect;
        private int width;
        private int height;
        private DepthImageFrame depthFrame;
        private bool gestureStatus;

        private DateTime lastTime = DateTime.Now;
        private DateTime cur;
        private DateTime startTimer,startTimerVertical;
        private int fps;
        List<Joint> lHandJointList = new List<Joint>();
        List<Joint> rHandJointList = new List<Joint>();
        List<Joint> spineJointList = new List<Joint>();
        List<int> lHandDepList = new List<int>();
        List<int> rHandDepList = new List<int>();
        List<int> spineDepList = new List<int>();
        Joint rHip;
        public void updateMovement(Joint lHand, Joint rHand, Joint spine, Joint rHip, DepthImageFrame depthFrame)
        {
            this.rHip = rHip;
            lHandJointList.Add(lHand);
            rHandJointList.Add(rHand);
            spineJointList.Add(spine);
            this.depthFrame = depthFrame;
            lHandDepList.Add(depthFrame.MapFromSkeletonPoint(lHand.Position).Depth); //this method is map joint to depthFrame position and then
            rHandDepList.Add(depthFrame.MapFromSkeletonPoint(rHand.Position).Depth); //use that position to find depth value on depthFrame
            spineDepList.Add(depthFrame.MapFromSkeletonPoint(spine.Position).Depth);

            if (lHandJointList.Count >= 50) //ให้ list limit เผื่อแค่ 50 พอ เพราะ fps มันอยู่ประมาณ 25-50 frame และเราจะใช้แค่ 0.5 วิ
            {
                lHandJointList.RemoveAt(0); //\\
                spineJointList.RemoveAt(0);   //XX ลบตัวแรกออก (ใช้ structure แบบ Queue)หน้
                rHandJointList.RemoveAt(0); ////
                lHandDepList.RemoveAt(0);
                rHandDepList.RemoveAt(0);
                spineDepList.RemoveAt(0);

            }

            cur = DateTime.Now;
            int difTime = cur.Millisecond - lastTime.Millisecond; //เวลาเป็น millisec ระหว่างเฟรมปัจจุบัน กับเฟรมก่อนา
            //mainPage.setOKLabel("fps : " + difTime);


            if (flag == false && (Math.Abs((cur.Second*1000+cur.Millisecond) - (startTimer.Second*1000+startTimer.Millisecond)) > 500))  //flag is use for delay the gesture after 
            {                                                                                       //the last one is activate
                flag = true;
                //Console.WriteLine("\nCheck Horizental Delay Time : " + cur.Second * 1000 + cur.Millisecond + " : " + startTimer.Second * 1000 + startTimer.Millisecond);
            }
            if (flagVertical == false && (Math.Abs(cur.Second - startTimerVertical.Second) > 1))
            { //this flagVertical is 
                flagVertical = true;                                                                                //only for Vertical Swipe Delay
                //Console.WriteLine("\nCurrent : " + cur.Second + "  start : " + startTimerVertical.Second);
            }


            lastTime = cur;
            if (difTime == 0)
                fps = 0;
            else
                fps = Math.Max(1000 / difTime, 0); //หา fps (ถ้าไม่ Max ไว้ มันจะมีโอกาสติดลบ)

            gestureStatus = rHandJointList.Count > fps / 2 && !spineMoved(depthFrame) && flag; //if true -> begin gesture

        }

        public bool spineMoved(DepthImageFrame depthFrame) //return false คือตัวไม่ขยับ
        {
            int listIndex = lHandJointList.Count - 1;
            int spineDepth = depthFrame.MapFromSkeletonPoint(spineJointList.Last().Position).Depth;

            //page.showMessageBox("listSize : " + listIndex + "\nfps : " + fps);

            int pastSpineDepth = spineDepList.ElementAt(listIndex - fps / 2);

            double spineX = spineJointList.Last().Position.X;
            double pastSpineX = spineJointList.ElementAt(listIndex - fps / 2).Position.X;

            int spineDepMoved = Math.Abs(pastSpineDepth - spineDepth);//จะถือว่าเป็นการกด หรือถอยมือออก เมื่อตัวอยู่กับที่เท่านั้น
            double spineXMoved = Math.Abs(spineX - pastSpineX);

            if (spineDepMoved < 100 && spineXMoved < 0.05 && spineX != 0 && spineDepth != 0) /**/ return false;
            else return true;
        }
        //วิธีใช้ method คือ เทียบระหว่าง ณ เวลาปัจจุบัน กับ 0.5 วิก่อนหน้า 
        //ถ้ามืออยู่กับที่(ขยับไม่เกินค่าๆหนึ่งที่กำหนดไว้)จะ return 0
        //ถ้ามือขยับเข้า จะ return 1
        //ถ้ามือขยับออก จะ return -1     
        //จะทำ method นี้ ต้องเรียกใช้ updateMovement() ก่อนเสมอ
        public int lHandPushed(DepthImageFrame depthFrame)
        {
            if (gestureStatus)
            {
                int listIndex = lHandJointList.Count - 1;
                double handMovedX = Math.Abs(lHandJointList.Last().Position.X - lHandJointList[listIndex - fps / 3].Position.X);
                double handMovedY = Math.Abs(lHandJointList.Last().Position.Y - lHandJointList[listIndex - fps / 3].Position.Y);
                if (handMovedX < 0.04 && handMovedY < 0.04) //ถ้ามือขยับในแกน X,Y เกินที่กำหนด ก็ไม่ต้องเข้าไปเช็ค
                {
                    int handDepth = depthFrame.MapFromSkeletonPoint(lHandJointList.Last().Position).Depth; //ความลึกของมือในปัจจุบัน

                    int pastHandDepth = lHandDepList.ElementAt(listIndex - fps / 2); //ความลึกของมือเมื่อ 0.5 วิที่แล้ว 

                    int handMovedDep = pastHandDepth - handDepth; //depth ที่มือขยับโดยดูระหว่างวินาทีปัจจุบัน กับ 0.5 วิ ก่อนหน้า

                    if (handMovedDep > 300 /*น่าจะใช้ประมาณ 300*/)
                    {
                        //mainPage.showMessageBox("aaaaaaaa");
                        return 1;
                    }
                    else if (handMovedDep < -300) //ดึงออกเกิน 300
                        return -1;
                }
            }
            return 0;
        }

        // กดมือขวา
        public int rHandPushed(DepthImageFrame depthFrame)
        {
            if (gestureStatus)
            {
                int listIndex = rHandJointList.Count - 1;
                double handMovedX = Math.Abs(rHandJointList.Last().Position.X - rHandJointList[listIndex - fps / 3].Position.X);
                double handMovedY = Math.Abs(rHandJointList.Last().Position.Y - rHandJointList[listIndex - fps / 3].Position.Y);


                if (handMovedX < 0.04 && handMovedY < 0.04)
                {
                    int handDepth = depthFrame.MapFromSkeletonPoint(rHandJointList.Last().Position).Depth;//ความลึกข้องมือใน ปัจจุบัน

                    int pastHandDepth = rHandDepList.ElementAt(listIndex - fps / 2); //ความลึกของมือเมื่อ 0.5 วิที่แล้ว 

                    int handMovedDep = pastHandDepth - handDepth; //depth ที่มือขยับโดยดูระหว่างวินาทีปัจจุบัน กับ 0.5 วิ ก่อนหน้า
                    //mainPage.setOKLabel(fps + "aaaaa");
                    if (handMovedDep > 300 /*น่าจะใช้ประมาณ 300*/  )
                        return 1;
                    else if (handMovedDep < -300) //ดึงออกเกิน 300
                        return -1;
                }
            }
            return 0;
        }


        bool flag = true;
        bool flagVertical = true;
        public string verticalStat { get; set; }
        public int rHandHSwipe() //return 0 : ไม่สไลด์, 1 : สไลด์ขวา, -1 : สไลด์ซ้าย
        {
            //Console.WriteLine("\nFLAG : " + flag);
            if (gestureStatus && flag)
            {
                int listIndex = rHandJointList.Count - 1;

                double pastRHandX = rHandJointList[listIndex - fps / 3].Position.X;
                double rHandX = rHandJointList.Last().Position.X;

                double handMoved = rHandX - pastRHandX;

                //if (handMoved > 0.35)
                //{
                //    //flag = false; //ถ้ามีการ slide มือ ให้ตั้ง flag เป็น false เพื่อหยุดการ Gesture ไปชั่วขณะ
                //    //startTimer = DateTime.Now;
                //    //Console.WriteLine("\nDateTime.now : " + DateTime.Now.Second);

                //    //return 1;
                //}

                if (handMoved < -0.35)
                {
                    flag = false;
                    startTimer = DateTime.Now;
                    return -1;
                }
                else
                    return 0;
            }
            return 0;
        }

        public int rHandVSwipe() //return 0 : ไม่สไลด์, 1 : สไลด์ขึ้น, -1 : สไลด์ล่าง
        {
            if (gestureStatus && flagVertical)
            {
                int listIndex = rHandJointList.Count - 1;
                Console.WriteLine("\nFPS : "+fps+" : "+fps/3);
                double firstRHandY = rHandJointList[Math.Max(listIndex - (fps / 4 + fps / 3),0)].Position.Y;
                double movedRHandY = rHandJointList[listIndex - (fps / 3)].Position.Y;
                double lastRHandY = rHandJointList.Last().Position.Y;

                double firstRHandYP = kinect.getRHandPosition(width, height, rHandJointList[Math.Max(listIndex - (fps / 4 + fps / 3), 0)]).Y;
                //double movedRHandYP = kinect.getRHandPosition(width, height, rHandJointList[listIndex - (fps / 3)]).Y;
                //double lastRHandYP = kinect.getRHandPosition(width, height, rHandJointList.Last()).Y;

                if (lastRHandY < rHip.Position.Y - 0.2f || movedRHandY < rHip.Position.Y - 0.2f) return 0;

                double handMoved = movedRHandY - firstRHandY;
                double handStill = Math.Abs(movedRHandY - lastRHandY);

                if (handMoved > 0.3 && handStill < 0.1 && verticalStat.Equals("down") )
                {
                    flagVertical = false; //ถ้ามีการ slide มือ ให้ตั้ง flag เป็น false เพื่อหยุดการ Gesture ไปชั่วขณะ
                    startTimerVertical = DateTime.Now;
                    verticalStat = "up";
                    return 1;
                }

                else if (handMoved < -0.3 && handStill < 0.1 && verticalStat.Equals("up") && firstRHandYP < 150)
                {
                    flagVertical = false;
                    startTimerVertical = DateTime.Now;
                    verticalStat = "down";
                    return -1;
                }
                else
                    return 0;
            }
            return 0;
        }





        public int lHandHSwipe() //return 0 : ไม่สไลด์, 1 : สไลด์ขวา, -1 : สไลด์ซ้าย
        {
            if (gestureStatus && flag)
            {
                int listIndex = lHandJointList.Count - 1;

                double pastlHandX = lHandJointList[listIndex - fps / 3].Position.X;
                double lHandX = lHandJointList.Last().Position.X;

                double handMoved = lHandX - pastlHandX;

                if (handMoved > 0.35)
                {
                    flag = false; //ถ้ามีการ slide มือ ให้ตั้ง flag เป็น false เพื่อหยุดการ Gesture ไปชั่วขณะ
                    startTimer = DateTime.Now;
                    return 1;
                }

                //else if (handMoved < -0.35)
                //{
                //    //flag = false;
                //    //startTimer = DateTime.Now;
                //    //return -1;
                //}
                else
                    return 0;
            }
            return 0;
        }
        
        public int lHandVSwipe() //return 0 : ไม่สไลด์, 1 : สไลด์ขึ้น, -1 : สไลด์ล่าง
        {
            if (gestureStatus && flagVertical)
            {
                int listIndex = lHandJointList.Count - 1;
                
                double firstLHandY = lHandJointList[Math.Max(listIndex - (fps / 4 + fps / 3), 0)].Position.Y;
                double movedLHandY = lHandJointList[listIndex - (fps / 3)].Position.Y;
                double lastLHandY = lHandJointList.Last().Position.Y;

                double firstLHandYP = kinect.getLHandPosition(width, height, lHandJointList[Math.Max(listIndex - (fps / 4 + fps / 3), 0)]).Y;

                if (lastLHandY < rHip.Position.Y - 0.1f || movedLHandY < rHip.Position.Y - 0.1f) return 0;

                double handMoved = movedLHandY - firstLHandY;
                double handStill = Math.Abs(movedLHandY - lastLHandY);

                if (handMoved > 0.3 && handStill < 0.1 && verticalStat.Equals("down"))
                {
                    flagVertical = false; //ถ้ามีการ slide มือ ให้ตั้ง flag เป็น false เพื่อหยุดการ Gesture ไปชั่วขณะ
                    startTimerVertical = DateTime.Now;
                    verticalStat = "up";
                    return 1;
                }

                else if (handMoved < -0.3 && handStill < 0.1 && verticalStat.Equals("up") && firstLHandYP < 150)
                {
                    flagVertical = false;
                    startTimerVertical = DateTime.Now;
                    verticalStat = "down";
                    return -1;
                }
                else
                    return 0;
            }
            return 0;
        }




        public bool chkMoveStatus()//ถ้าตัวไม่ขยับ และเก็บครบ 0.5 วิแล้ว จะ return true
        {
            return rHandJointList.Count > fps / 2 && !spineMoved(depthFrame) && flag;
        }

    }


    //class Gesture
    //{
    //    public Gesture(int width, int height, Kinect kinect)
    //    {
    //        this.width = width;
    //        this.height = height;
    //        this.kinect = kinect;
    //    }

    //    private int width;
    //    private int height;
    //    private Kinect kinect;
    //    //private PlanarImage image;
    //    private bool moveStatus;

    //    private DateTime lastTime = DateTime.Now;
    //    private DateTime cur;
    //    private DateTime startTimer;
    //    private int fps;
    //    List<Joint> lHandJointList = new List<Joint>();
    //    List<Joint> rHandJointList = new List<Joint>();
    //    List<Joint> spineJointList = new List<Joint>();
    //    List<int> lHandDepList = new List<int>();
    //    List<int> rHandDepList = new List<int>();
    //    List<int> spineDepList = new List<int>();
    //    private int countRHand = 0;

    //    public void updateMovement(Joint lHand, Joint rHand, Joint rWrist, Joint spine, PlanarImage image)
    //    {

    //        lHandJointList.Add(lHand);
    //        rHandJointList.Add(rHand);
    //        spineJointList.Add(spine);

    //        this.image = image;

    //        int lHandDep = kinect.getRealDepth(kinect.getDepthIndexFromDepth(lHand), image.Bits);
    //        int rHandDep = kinect.getRealDepth(kinect.getDepthIndexFromDepth(rHand), image.Bits);
    //        int spineDep = kinect.getRealDepth(kinect.getDepthIndexFromDepth(spine), image.Bits);
    //        int rWristDep = kinect.getRealDepth(kinect.getDepthIndexFromDepth(rWrist), image.Bits);

    //        rHandDepList.Add(rHandDep);
    //        lHandDepList.Add(lHandDep);
    //        spineDepList.Add(spineDep);

    //        int index = rHandDepList.Count - 1; //ตัวที่ index คือตัวสุดท้ายของ List




    //        if (rHandDepList.Count > 3 && Math.Abs(rHandDepList[index] - rHandDepList[index - 1]) > 100 && countRHand <= 30)//&& rHandDepList[index] != 0
    //        //Math.Abs(rHandDepList[index] - rHandDepList[index - 1]) > 100 เพราะบางที มือไม่ได้ขยับ แต่ค่ามันเด้งไปเอง (เพราะตำแหน่งของ skeleton มันเด้งออกจากตำแหน่งจริงของมือตาม pixel Depth)
    //        //(ในความเป็นจริงโอกาสน้อยอยู่แล้วที่ภายในเฟรมเดียว มือจะขยับได้ Dep>100), (ค่าเด้ง เกิดจาก ตำแหน่งของ Joint ที่บอกตำแหน่งมือ มันจับจุดเด้งออกจากตำแหน่งมือจริง ทำให้กลายเป็นความลึกของ background หลังมือแทน)
    //        {
    //            if (rWristDep - rHandDepList[index - 1] > 100) //ถ้าจุดที่มือเด้ง ลองเปลี่ยนไปเช็คจุดที่ข้อมือแทน ถ้า depth ของข้อมือ ไม่ได้เด้งไปตามมือ ก็ใช้ความลึกของข้อมือไปแทน
    //            {
    //                //ถ้าจุดที่ข้อมือก็ความลึกเปลี่ยนมาก เกิน 100 ไปเรียกใช้ Medthod CorrectDepth
    //                correctDepth(rHandJointList, rHandDepList);
    //                countRHand++;   // ใช้นับจน.ที่มีการเรียกใช้ correctDepth ถ้ามีการใช้มากเกิน อาจเป็นไปได้ว่า ที่จริงคนออกจากจอไปแล้ว กลับเข้ามาใหม่ แล้วความลึกของมือ มันเปลี่ยนจากเดิมไปมาก
    //                // โดยที่จริงๆ ไม่ได้เกิดการเด้งของตำแหน่งมือ
    //            }
    //            else
    //            {

    //                rHandDepList[index] = rWristDep; //ใช้ความลึกของข้อมือแทน
    //                rHandJointList[index] = jointForcast(rHandJointList); //เปลี่ยน Joint อันสุดท้ายของมือเป็น forcastJoint
    //            }


    //        }
    //        else
    //        {
    //            if (countRHand == 31) Console.WriteLine("COUNTRHANDDDDDDDDDDDDDDDDD");
    //            countRHand = 0;
    //        }





    //        if (rHandDepList.Count > 2 && Math.Abs(rHandDepList.Last() - rHandDepList[rHandDepList.Count - 2]) > 100)
    //        {
    //            Console.WriteLine("aaaaaaaaaaaaaaaaaaaaaaaaa");

    //        }
    //        Console.WriteLine("rHand Depth : " + rHandDep + ", real Depth : " + rHandDepList.Last() + ", Spine : " + spineDep + ", rWristDep : " + rWristDep);

    //        //mainPage.setTextBox(rHandDepList.Last() + "");


    //        if (rHandDepList.Count >= 50) //ให้ list limit เผื่อแค่ 50 พอ เพราะ fps มันอยู่ประมาณ 25-50 frame/Sec และเราจะใช้แค่ 0.5 วิ
    //        {
    //            lHandJointList.RemoveAt(0); //      \\
    //            spineJointList.RemoveAt(0); //       \\
    //            rHandJointList.RemoveAt(0); //        \\
    //            //          >> ลบตัวแรกออก (ใช้ structure แบบ Queue)
    //            lHandDepList.RemoveAt(0);   //        //
    //            rHandDepList.RemoveAt(0);   //       //
    //            spineDepList.RemoveAt(0);   //      //
    //        }

    //        cur = DateTime.Now;
    //        int difTime = cur.Millisecond - lastTime.Millisecond; //เวลาเป็น millisec ระหว่างเฟรมปัจจุบัน กับเฟรมก่อน
    //        //mainPage.setOKLabel("fps : " + difTime);




    //        if (flag == false && ((cur.Second + 60) - startTimer.Second) % 60 > 1 && ((cur.Millisecond + 1000) - startTimer.Millisecond) % 1000 > 900)  //รอครบ 0.9 วิ ค่อยรับ gesture อีกครั้ง
    //        {                                                                                   //วิธีใช้ หลังสไลด์ภาพแล้ว หยุดรับ gesture ไป 0.9 วิ
    //            flag = true;
    //        }


    //        lastTime = cur;
    //        if (difTime == 0)
    //            fps = 0;
    //        else
    //            fps = Math.Max(1000 / difTime, 0); //หา fps (ถ้าไม่ Max ไว้ มันจะมีโอกาสติดลบ)

    //        moveStatus = rHandDepList.Count > fps / 2 && !spineMoved(image) && flag;  //ถ้ายังมีข้อมูลไม่ถึง fps/2 อย่าเพิ่งเข้าเงื่อนไข Gesture
    //        //spineMoved จะเป็น true เมื่อ spine มีการขยับ
    //        //คือเงื่อนไขที่ใช้หยุดรับ Gesture หลังจากเพิ่งมาการรับ Gesture ได้
    //        //ถ้า moveStatus เป็น true คือ OK ให้คิดเงื่อนไขการรับ Gesture



    //        //moveStatus ตัวนี้จะเอาไปใช้เช็คก่อนรับ gesture ต่างๆ

    //        //mainPage.setTextBox("Gesture Stat : " + moveStatus);
    //        //mainPage.setTextBox(fps + "");

    //    }

    //    public bool spineMoved(PlanarImage image)
    //    {
    //        int listIndex = lHandJointList.Count - 1;
    //        int indxSpine = kinect.getDepthIndexFromDepth(spineJointList.Last());
    //        int spineDepth = kinect.getRealDepth(indxSpine, image.Bits);
    //        //page.showMessageBox("listSize : " + listIndex + "\nfps : " + fps);
    //        indxSpine = kinect.getDepthIndexFromDepth(spineJointList.ElementAt(listIndex - fps / 2));
    //        int pastSpineDepth = spineDepList.ElementAt(listIndex - fps / 2);

    //        double spineX = spineJointList.Last().Position.X;
    //        double pastSpineX = spineJointList.ElementAt(listIndex - fps / 2).Position.X;

    //        int spineDepMoved = Math.Abs(pastSpineDepth - spineDepth);//จะถือว่าเป็นการกด หรือถอยมือออก เมื่อตัวอยู่กับที่เท่ากัน
    //        double spineXMoved = Math.Abs(spineX - pastSpineX);

    //        if (spineDepMoved < 100 && spineXMoved < 0.05 && spineX != 0 && spineDepth != 0) /**/ return false;
    //        else return true;
    //    }

    //    //วิธีใช้ method คือ เทียบระหว่าง ณ เวลาปัจจุบัน กับ 0.5 วิก่อนหน้า 
    //    //ถ้ามืออยู่กับที่(ขยับไม่เกินค่าๆหนึ่งที่กำหนดไว้)จะ return 0
    //    //ถ้ามือขยับเข้า จะ return 1
    //    //ถ้ามือขยับออก จะ return -1     
    //    //จะทำ method นี้ ต้องเรียกใช้ updateMovement() ก่อนเสมอ
    //    public int lHandPushed(PlanarImage image)
    //    {
    //        if (moveStatus)
    //        {
    //            int listIndex = lHandJointList.Count - 1;
    //            double handMovedX = Math.Abs(lHandJointList.Last().Position.X - lHandJointList[listIndex - fps / 3].Position.X);
    //            double handMovedY = Math.Abs(lHandJointList.Last().Position.Y - lHandJointList[listIndex - fps / 3].Position.Y);
    //            if (handMovedX < 0.04 && handMovedY < 0.04) //ถ้ามือขยับในแกน X,Y เกินที่กำหนด ก็ไม่ต้องเข้าไปเช็ค
    //            {
    //                int indxHand = kinect.getDepthIndexFromDepth(lHandJointList.Last());
    //                int handDepth = kinect.getRealDepth(indxHand, image.Bits); //ความลึกข้องมือใน ปัจจุบัน

    //                int pastHandDepth = lHandDepList.ElementAt(listIndex - fps / 2); //ความลึกของมือเมื่อ 0.5 วิที่แล้ว 

    //                int handMovedDep = pastHandDepth - handDepth; //depth ที่มือขยับโดยดูระหว่างวินาทีปัจจุบัน กับ 0.5 วิ ก่อนหน้า

    //                if (handMovedDep > 200 /*น่าจะใช้ประมาณ 300*/)
    //                {

    //                    //mainPage.showMessageBox("aaaaaaaa");
    //                    return 1;
    //                }
    //                else if (handMovedDep < -200) //ดึงออกเกิน 300
    //                    return -1;
    //            }
    //        }
    //        return 0;
    //    }

    //    // กดมือขวา
    //    public int rHandPushed(PlanarImage image)
    //    {
    //        if (moveStatus)
    //        {
    //            int listIndex = rHandJointList.Count - 1;
    //            double handMovedX = Math.Abs(rHandJointList.Last().Position.X - rHandJointList[listIndex - fps / 4].Position.X);
    //            double handMovedY = Math.Abs(rHandJointList.Last().Position.Y - rHandJointList[listIndex - fps / 4].Position.Y);

    //            if (handMovedX < 0.04 && handMovedY < 0.04) //ถ้ามือไม่ขยับในแนว X,Y เกิน 0.04 ในเวลา 0.25 วิ ถึงจะเข้าไปเช็ค gesture
    //            {


    //                int indxHand = kinect.getDepthIndexFromDepth(rHandJointList.Last());
    //                int handDepth = kinect.getRealDepth(indxHand, image.Bits); //ความลึกข้องมือใน ปัจจุบัน

    //                int pastHandDepth = rHandDepList.ElementAt(listIndex - fps / 3); //ความลึกของมือเมื่อ 0.33 วิที่แล้ว 

    //                int handMovedDep = pastHandDepth - handDepth; //depth ที่มือขยับโดยดูระหว่างวินาทีปัจจุบัน กับ 0.33 วิ ก่อนหน้า

    //                //mainPage.setTextBox(handMovedDep+"");
    //                if (handMovedDep > 150 /*น่าจะใช้ประมาณ 150*/ && handDepth != 0)
    //                {
    //                    //mainPage.setTextBox(pastHandDepth + " - " + handDepth + " = " + handMovedDep + "");

    //                    moveStatus = false;
    //                    flag = false; //ถ้ามีการ slide มือ ให้ตั้ง flag เป็น false เพื่อหยุดการ Gesture ไปชั่วขณะ
    //                    startTimer = DateTime.Now;
    //                    return 1;
    //                }

    //                else if (handMovedDep < -150) //ดึงออกเกิน 150
    //                    return -1;
    //                else
    //                    return 0;
    //            }
    //            //mainPage.setTextBox("False");
    //        }
    //        return 0;
    //    }


    //    bool flag = true;
    //    public int rHandSlide() //return 0 : ไม่สไลด์, 1 : สไลด์ขวา, -1 : สไลด์ซ้าย
    //    {
    //        if (moveStatus)
    //        {
    //            int listIndex = rHandJointList.Count - 1;

    //            double pastRHandX = rHandJointList[listIndex - fps / 6].Position.X;
    //            double rHandX = rHandJointList.Last().Position.X;

    //            double handMoved = rHandX - pastRHandX;
    //            //Console.WriteLine(fps/4 + " " + rHandX + " - " + pastRHandX + " = " + handMoved);
    //            if (handMoved > 0.25)
    //            {
    //                Console.WriteLine("Silde R : " + rHandX + " - " + pastRHandX + " = " + handMoved);
    //                moveStatus = false;
    //                flag = false; //ถ้ามีการ slide มือ ให้ตั้ง flag เป็น false เพื่อหยุดการ Gesture ไปชั่วขณะ
    //                startTimer = DateTime.Now;
    //                return 1;
    //            }

    //            else if (handMoved < -0.25)
    //            {
    //                Console.WriteLine("Slide L : " + rHandX + " - " + pastRHandX + " = " + handMoved);
    //                moveStatus = false;
    //                flag = false;
    //                startTimer = DateTime.Now;
    //                return -1;
    //            }

    //        }
    //        return 0;
    //    }

    //    public int lHandSlide() //return 0 : ไม่สไลด์, 1 : สไลด์ขวา, -1 : สไลด์ซ้าย
    //    {
    //        if (moveStatus)
    //        {
    //            int listIndex = lHandJointList.Count - 1;

    //            double pastlHandX = lHandJointList[listIndex - fps / 6].Position.X;
    //            double lHandX = lHandJointList.Last().Position.X;

    //            double handMoved = lHandX - pastlHandX;

    //            if (handMoved > 0.25)
    //            {
    //                flag = false; //ถ้ามีการ slide มือ ให้ตั้ง flag เป็น false เพื่อหยุดการ Gesture ไปชั่วขณะ
    //                startTimer = DateTime.Now;
    //                return 1;
    //            }

    //            else if (handMoved < -0.25)
    //            {
    //                flag = false;
    //                startTimer = DateTime.Now;
    //                return -1;
    //            }
    //            else
    //                return 0;
    //        }
    //        return 0;
    //    }

    //    public void correctDepth(List<Joint> jointList, List<int> depList)
    //    {
    //        Joint lastJoint = jointList.Last();

    //        int lastDep;
    //        int nextDep = depList[depList.Count - 2];

    //        Joint forcastJoint = jointForcast(jointList);
    //        Joint nextJoint = jointList[jointList.Count - 2];


    //        /////////////// จะได้ตัวเลือกในการทำนาย Joint ใหม่ เป็น ทำนายว่าอยู่ที่เดิม<nextJoint1> กับ ทำนายว่าวิ่งไปด้วยความเร็วเท่าเดิมในทิศทางเดิม<forcastJoint> /////////////////

    //        int dep1 = kinect.getRealDepth(kinect.getDepthIndexFromDepth(nextJoint), image.Bits);
    //        int dep2 = kinect.getRealDepth(kinect.getDepthIndexFromDepth(forcastJoint), image.Bits);

    //        //// จะเลือก choice ไหนจากสองตัวเลือก จะตัดสินจาก joint ใหม่ ที่ทำให้ Dep ต่างจากเดิม<nextJoint2, nextDep>น้อยที่สุด
    //        //// ยกเว้นกรณีที่ทั้ง dep1, dep2 เด้งไปทั้งคู่ คือที่ตำแหน่ง nextJoint, forcastJoint detect ไม่โดนมือ ก็ให้เอาค่าความลึกเดิม(nextDep) ใส่เข้าไปแทนเลย
    //        if (Math.Abs(nextDep - dep2) > 100 && Math.Abs(nextDep - dep1) > 100)
    //        {
    //            lastJoint.Position = forcastJoint.Position;
    //            lastDep = nextDep; //เอาความลึกเก่าใส่เข้าไปเลย
    //        }
    //        else if (Math.Abs(nextDep - dep2) < Math.Abs(nextDep - dep1))
    //        {
    //            lastJoint.Position = forcastJoint.Position;
    //            lastDep = dep2;
    //        }
    //        else
    //        {
    //            lastJoint.Position = nextJoint.Position;
    //            lastDep = dep1;
    //        }
    //        Console.WriteLine("old : " + nextDep + ", dep1 : " + dep1 + ", dep2 : " + dep2);
    //        /////// แก้ List ตัวสุดท้าย (ตัวปัจจุบัน) ให้เป็นค่าทำนายไว้ ///////
    //        jointList[jointList.Count - 1] = lastJoint;
    //        depList[depList.Count - 1] = lastDep;

    //    }

    //    //public void correctDepth(List<Joint> jointList, List<int> depList)
    //    //{
    //    //    //Joint lastJoint = jointList.Last();

    //    //    //int lastDep;
    //    //    //int nextDep = depList[depList.Count - 2];

    //    //    Joint forcastJoint = jointForcast(jointList, depList);


    //    //    int forcastDep = kinect.getRealDepth(kinect.getDepthIndexFromDepth(forcastJoint), image.Bits);
    //    //    Console.WriteLine("Dep : " + forcastDep + ", LastDep : "+depList[depList.Count-2]);
    //    //    /////// แก้ List ตัวสุดท้าย (ตัวปัจจุบัน) ให้เป็นค่าทำนายไว้ ///////
    //    //    jointList[jointList.Count - 1] = forcastJoint;
    //    //    depList[depList.Count - 1] = forcastDep;

    //    //}

    //    public Joint jointForcast(List<Joint> jointList)
    //    {
    //        Joint forcastJoint = new Joint();
    //        Joint nextJoint1 = jointList[jointList.Count - 2];
    //        Joint nextJoint2 = jointList[jointList.Count - 3];

    //        ////////// ทำนายค่า x,y ใหม่ให้กับ forcastJoint ///////////////////
    //        //จะทำนายว่า joint นั้น วิ่งด้วยความเร็วเท่าเดิม ในทิศทางเดิม โดยดูจาก Frame ก่อนหน้า 2 Frame
    //        Vector v = new Vector();
    //        v = nextJoint1.Position;
    //        v.X = nextJoint1.Position.X + (nextJoint1.Position.X - nextJoint2.Position.X);
    //        v.Y = nextJoint1.Position.Y + (nextJoint1.Position.Y - nextJoint2.Position.Y);

    //        forcastJoint.Position = v;
    //        return forcastJoint;

    //    }


    //    public bool chkMoveStatus()//ถ้าตัวไม่ขยับ และเก็บครบ 0.5 วิแล้ว จะ return true
    //    {
    //        return rHandJointList.Count > fps / 2 && !spineMoved(image) && flag;
    //    }

    //    public Joint getCorrectedRhand()
    //    {
    //        return rHandJointList.Last();
    //    }

    //    public void clearGesture()
    //    {
    //        lHandJointList.Clear();
    //        rHandJointList.Clear();
    //        spineJointList.Clear();
    //        lHandDepList.Clear();
    //        rHandDepList.Clear();
    //        spineDepList.Clear();
    //    }
    //}
}
